import tkinter as tk
from tkinter import ttk
from models.features import FeatureClass, ScriptStatus, get_feature_subclasses
from view.panel.script1 import Script1Class
from view.panel.script2 import Script2Class


class ScrollableFrame(tk.Frame):
    """
    A scrollable frame widget that allows vertical scrolling of its content.
    """

    def __init__(self, parent, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)

        # Create a canvas and vertical scrollbar
        self.canvas = tk.Canvas(self)
        self.scrollbar = ttk.Scrollbar(self, orient="vertical", command=self.canvas.yview)
        self.scrollable_frame = ttk.Frame(self.canvas)

        # Configure scrollbar and canvas interaction
        self.scrollable_frame.bind("<Configure>", lambda e: self.canvas.configure(scrollregion=self.canvas.bbox("all")))
        self.canvas.create_window((0, 0), window=self.scrollable_frame, anchor="nw")
        self.canvas.configure(yscrollcommand=self.scrollbar.set)

        # Place canvas and scrollbar within parent frame
        self.canvas.grid(row=0, column=0, sticky="nsew")
        self.scrollbar.grid(row=0, column=1, sticky="ns")

        # Configure grid weights to allow frame expansion
        self.grid_rowconfigure(0, weight=1)
        self.grid_columnconfigure(0, weight=1)


class Application(tk.Tk):
    """
    Main application class that manages GUI setup and script selection.
    """

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Initialize main window
        self.title("Feature Application")
        self.geometry("800x500")

        # Initialize instance variables
        self.current_feature = None

        # Create GUI components
        self.create_top_panel()
        self.create_middle_top_panel()
        self.create_bottom_log_panel()
        self.load_scripts()

    def create_top_panel(self):
        """
        Create the top panel with script selection dropdown, status label, and status circle.
        """
        self.top_panel = ttk.Frame(self)
        self.top_panel.grid(row=0, column=0, columnspan=3, sticky="ew")

        self.script_selector_label = ttk.Label(self.top_panel, text="Select Script:")
        self.script_selector_label.grid(row=0, column=0, padx=5, pady=5, sticky="ew")

        self.script_dropdown = ttk.Combobox(self.top_panel)
        self.script_dropdown.grid(row=0, column=1, padx=10, pady=10)

        self.status_label = ttk.Label(self.top_panel, text="状态: 待机", font=("Arial", 12))
        self.status_label.grid(row=0, column=2, padx=5, pady=5, sticky="ew")

        self.status_circle = tk.Canvas(self.top_panel, width=20, height=20)
        self.status_circle.grid(row=0, column=3, padx=5, pady=5)

        self.update_status_circle(ScriptStatus.IDLE)

    def create_middle_top_panel(self):
        """
        Create the scrollable middle panel where script components will be displayed.
        """
        self.panel_frame = ScrollableFrame(self)
        self.panel_frame.grid(row=1, column=0, sticky="nsew")

    def load_scripts(self):
        """
        Load available script names into the script dropdown and bind event handlers.
        """
        self.feature_classes = get_feature_subclasses()
        self.script_names = [cls.script_name for cls in self.feature_classes]
        self.script_dropdown["values"] = self.script_names
        self.script_dropdown.current(0)
        self.script_dropdown.bind("<<ComboboxSelected>>", self.change_script_panel)
        self.change_script_panel()

    def change_script_panel(self, event=None):
        """
        Change the displayed script panel based on the selected script in the dropdown.
        """
        selected_script_name = self.script_dropdown.get()
        selected_script_class = next((cls for cls in self.feature_classes if cls.script_name == selected_script_name),
                                     None)

        if selected_script_class:
            if self.current_feature:
                self.current_feature.clear_inputs()

            self.current_feature = selected_script_class(self)
            self.current_feature.create_panel(self.panel_frame)
            self.current_feature.set_log_display(self.log_box)

    def update_status_label(self, status_text):
        """
        Update the status label with the provided status text.
        """
        self.status_label.config(text=f"状态: {status_text}")

    def update_status_circle(self, status):
        """
        Update the status circle color based on the provided status.
        """
        color = {
            ScriptStatus.IDLE: 'gray',
            ScriptStatus.RUNNING: 'orange',
            ScriptStatus.SUCCESS: 'green',
            ScriptStatus.FAILURE: 'red'
        }[status]

        self.status_circle.delete("all")
        self.status_circle.create_oval(2, 2, 18, 18, fill=color, outline='black')

    def create_bottom_log_panel(self):
        """
        Create the bottom panel with a text log box and scrollbar.
        """
        bottom_panel = ttk.Frame(self)
        bottom_panel.grid(row=3, column=0, columnspan=3, sticky="nsew")

        self.log_box = tk.Text(bottom_panel, height=10, wrap=tk.WORD)
        self.log_box.grid(row=0, column=0, padx=10, pady=10)

        scrollbar = tk.Scrollbar(bottom_panel, command=self.log_box.yview)
        scrollbar.grid(row=0, column=1, sticky='nsew')
        self.log_box.config(yscrollcommand=scrollbar.set)


if __name__ == "__main__":
    app = Application()
    app.mainloop()
